

#include <stdint.h>
#include <stddef.h>
#include <stdio.h>

#include "dbg_cli.h"


static uint32_t  esc_value = 0;
static int echo_mode = 1;

int cons_puts( const char * str )
{
	if ( echo_mode == 0 ) {
		return 0;
	}
	
	/**/
	printf( "%s", str );
	return 0;
}


int debug_cmd_echo( void * pctx, int argc, const char **argv )
{
	int iret;
	uint32_t  temp;
	
	/**/
	if ( argc < 2 ) {
		printf( "echo mode : %d\n", echo_mode );
		goto usage;
	}
	
	/**/
	iret = debug_str2uint( argv[1], &temp );
	if ( iret != 0 ) {
		printf( "mode fmt err, %d\n", iret );
		goto usage;
	}
	
	if ( temp == 0 ) {
		echo_mode = 0;
	} else {
		echo_mode = 1;
	}
	return 0;
	
	/**/
usage:
	printf( "usage : %s <0/1>\n", argv[0] );
	return 0;
}



static int proc_esc_sequences( uint8_t tch, uint32_t * pcd )
{
	uint32_t  temp = tch;

	/**/
	if ( esc_value == 0 )
	{
		if ( temp == 0x1b )
		{
			esc_value = 0x1b;
			return 1;
		}
		
		goto  try_post;
	}
	else if ( esc_value == 0x1b )
	{
		if ( temp == 0x5b )
		{
			esc_value = 0x1b5b;
			return 2;
		}
		else
		{
			/* error code? */
			esc_value = 0;
			return 3;
		}
	}
	else if ( esc_value == 0x1b5b )
	{
		temp = 0x5b00 | temp;
		esc_value = 0;
		goto try_post;
	}
	else
	{
		/* error code? */
		esc_value = 0;
		return 4;
	}
	
	
	/**/
try_post:
	*pcd = temp;
	return 0;
}



int cons_readline( const char * prompt, int max, char * spad )
{
	int iret;
	int sidx;
	uint32_t temp;
	
retry:
	/**/
	sidx = 0;
	cons_puts( prompt );
	
	while ( 1 ) {
		
		/* read from uart */
		iret = getchar();
		iret = proc_esc_sequences( (uint8_t)iret, &temp );
		if ( iret != 0 ) {
			continue;
		}
		
		/**/
		switch ( temp ) {
			
		case  0x5b41:		/* up arrow */
		case  0x5b42:	    /* down arrow */
			/* todo: history lines */
			break;
			
		case 0x7f:
		case 0x08:
			/* back space */
			if ( sidx > 0 )
			{
				sidx--;			
				cons_puts( "\b \b" );
			}
			break;

		case 0x03:
			/* ctrl + c : ??????. */
			break;

		case 0x0A:
		case 0x0D:
			/* enter */
			cons_puts( "\n" );
			
			/* empty line */
			if ( sidx <= 0 )
			{
				goto retry;
			}
		
			/**/
			spad[sidx] = '\0';
			return 0;
		
		case 0x09:
			/* tab >> space */
			temp = 0x20;

		case 0x20:
			/* line begin */
			if ( sidx <= 0 ) {
				break;
			}
			
		default:
			if ( temp > 0x7F )
			{
				/* nothing proc */
				break;
			}
			
			if ( sidx < max ) {
				
				spad[sidx] = (char)temp;
				sidx += 1;
				spad[sidx] = '\0';
				cons_puts( &spad[sidx - 1] );
				
			} else {
				sidx = 0;
				cons_puts( "\n\t:: too long, try again\n" );
				goto retry;
			}
			break;
		}
		
	}

}


